package com.qo.qsdk.ui;

import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.qo.qsdk.QSDK;
import com.qo.qsdk.QSDKApi;
import com.qo.qsdk.event.QSDKEvent;
import com.qo.qsdk.event.QSDKReceiver;
import com.qo.qsdk.event.QSDKSubscribe;
import com.qo.qsdk.http.QCommonResultBean;
import com.qo.qsdk.http.QCommonResultListBean;
import com.qo.qsdk.http.QResultCallback;
import com.qo.qsdk.http.QSDKHttp;
import com.qo.qsdk.model.HisModel;
import com.qo.qsdk.model.UserModel;
import com.qo.qsdk.ui.base.AccountView;
import com.qo.qsdk.ui.base.HisView;
import com.qo.qsdk.utils.Language;
import com.qo.qsdk.utils.LogManager;
import com.qo.qsdk.utils.PwdManager;
import com.qo.qsdk.utils.QSDKHelper;
import com.qo.qsdk.utils.ScreenUtil;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.google.android.gms.auth.api.signin.GoogleSignInStatusCodes.SIGN_IN_CANCELLED;

public class AccountActivity extends BaseActivity {

    private IAccount mAccountView;
    private static final String TAG = AccountActivity.class.getSimpleName();
    public static boolean isHis;
    public static boolean isBind;
    public static boolean isSwitch;
    private boolean isLoginInit;
    public static final String KEY = "firstGuest";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        PwdManager.getInstance().init(this);
        PwdManager.getInstance().setPwdManagerCountdownLister(new PwdManager.PwdManagerCountdownLister() {
            @Override
            public void update(int time) {

            }

            @Override
            public void start(int time) {
                PwdActivity.start(AccountActivity.this);
            }
        });
        mAccountView = new AccountView(this, new QSDKListener() {
            @Override
            public void onTerms() {
                FloatActivity.show(AccountActivity.this, Language.Login_Desc_Pro_1.toString(), QSDKHelper.getInstance().getConfigureModel().getInitModel().getTerms_url());
            }

            @Override
            public void onChangeLanguage() {
                QSDK.getInstance().toggleLanguage(AccountActivity.this);
            }

            @Override
            public void onProtocol() {
                FloatActivity.show(AccountActivity.this, Language.Login_Desc_Pro_3.toString(), QSDKHelper.getInstance().getConfigureModel().getInitModel().getPrivacy_url());
            }

            @Override
            public void onLoadingChange() {
                UserModel userModel = QSDKHelper.getInstance().getUserInfoModel(AccountActivity.this);
                if (!userModel.isGuest()) {
                    mAccountView.showLogin(AccountActivity.this);
                }else{
                    mAccountView.showBind(AccountActivity.this, getWaittingBindingUser());
                }
            }

            @Override
            public void onLoadingContinue() {
                loginToken();
            }

            @Override
            public void onLogin(String account, String pwd) {
                if (account.length() <= 0) {
                    TipActivity.tip(AccountActivity.this, Language.Login_Verify_Account_Empty.toString());
                    return;
                }
                if (pwd.length() <= 0) {
                    TipActivity.tip(AccountActivity.this, Language.Login_Verify_Pwd_Empty.toString());
                    return;
                }

                if (PwdManager.getInstance().getTime() > 0) {
                    TipActivity.tip(AccountActivity.this, Language.Pwd_Tip_L.toString() + PwdManager.getInstance().displayTime() + Language.Pwd_Tip_R.toString());
                    return;
                }


                showLoading();
                QSDKHttp.getInstance().loginAccount(AccountActivity.this, account, pwd, new QResultCallback<QCommonResultBean<UserModel>>() {
                    @Override
                    public void onSuccess(QCommonResultBean<UserModel> response) {
                        hideLoading();
                        response.getBody().setPass(pwd);
                        loginSuccess(UserModel.Type.Account, response.getBody());
                    }

                    @Override
                    public void onError(int code, String msg) {
                        hideLoading();
                        if (code == 1014 || code == 1011) {
                            PwdManager.getInstance().countDown(AccountActivity.this);
                            mAccountView.clearLoginPwd(AccountActivity.this);
                            if (PwdManager.getInstance().getTime() <= 0) TipActivity.tip(AccountActivity.this, msg);
                        }else{
                            TipActivity.tip(AccountActivity.this, msg);
                        }
                    }
                });
            }

            @Override
            public void onRegister(String account, String pwd) {
                if (account.length() <= 0) {
                    TipActivity.tip(AccountActivity.this, Language.Login_Verify_Account_Empty.toString());
                    return;
                }
                if (pwd.length() <= 0) {
                    TipActivity.tip(AccountActivity.this, Language.Login_Verify_Pwd_Empty.toString());
                    return;
                }
                showLoading();
                QSDKHttp.getInstance().registerAccount(AccountActivity.this, account, pwd, new QResultCallback<QCommonResultBean<UserModel>>() {
                    @Override
                    public void onSuccess(QCommonResultBean<UserModel> response) {
                        hideLoading();
                        response.getBody().setPass(pwd);
                        loginSuccess(UserModel.Type.Register, response.getBody());
                    }

                    @Override
                    public void onError(int code, String msg) {
                        hideLoading();
                        TipActivity.tip(AccountActivity.this, msg);
                    }
                });
            }

            @Override
            public void onLoginFb() {
                authFb(null);
            }

            @Override
            public void onLoginApple() {
                authApple(null);
            }

            @Override
            public void onLoginGoogle() {
                authGoogle(null);
            }

            @Override
            public void onLoginGuest() {
                loginGuest();
            }

            @Override
            public void onLoginInitGoogle() {
                authGoogle(null);
            }

            @Override
            public void onLoginInitFb() {
                authFb(null);
            }

            @Override
            public void onLoginInitApple() {
                authApple(null);
            }

            @Override
            public void onLoginInitGuest() {
                loginGuest();
            }

            @Override
            public void onLoginInitAccount() {
                mAccountView.showRegister(AccountActivity.this);
            }

            @Override
            public void onBindFb(UserModel u) {
                authFb(u);
            }

            @Override
            public void onBindApple(UserModel u) {
                authApple(u);
            }

            @Override
            public void onBindGoogle(UserModel u) {
                authGoogle(u);
            }

            @Override
            public void onBindAccount(UserModel userModel) {
                mAccountView.showBindQ(AccountActivity.this, userModel);
            }

            @Override
            public void onBindChange() {
                mAccountView.showLogin(AccountActivity.this);
            }

            @Override
            public void onBindContinue(boolean isFromGuestLogin, UserModel userModel) {
                if (isFromGuestLogin) {
                    loginSuccess(UserModel.Type.Guest, userModel);
                }else{
                    loginToken();
                }
            }

            @Override
            public void onBindQBtn(UserModel userModel, String account, String pwd) {
                showLoading();
                QSDKHttp.getInstance().bindAccount(AccountActivity.this, account, pwd, userModel.getToken(),
                        new QResultCallback<QCommonResultBean<UserModel>>() {
                            @Override
                            public void onSuccess(QCommonResultBean<UserModel> response) {
                                hideLoading();
                                response.getBody().setPass(pwd);
                                response.getBody().setToken(userModel.getToken());
                                loginSuccess(UserModel.Type.Register, response.getBody());
                            }

                            @Override
                            public void onError(int code, String msg) {
                                hideLoading();
                                TipActivity.tip(AccountActivity.this, msg);
                            }
                        }
                );
            }

            @Override
            public void onExitSuccess() {
                super.onExitSuccess();
            }

            @Override
            public void onExitCancel() {
                super.onExitCancel();
            }

            @Override
            public void onTipClose() {
                super.onTipClose();
            }

            @Override
            public void onFloatClose() {
                super.onFloatClose();
            }

            @Override
            public void onHisGoogle(String account) {
                authGoogle(null);
            }

            @Override
            public void onHisApple(String account) {
                authApple(null);
            }

            @Override
            public void onHisGuest(String account) {
                loginGuest();
            }

            @Override
            public void onHisAccount(String account) {
                mAccountView.showLogin(AccountActivity.this, account);
            }

            @Override
            public void onHisFacebook(String account) {
                authFb(null);
            }

            @Override
            public void onHisClose() {
                QSDK.getInstance().loginCancel();
                finish();
            }

            @Override
            public void onBindQClose(UserModel userModel) {
                mAccountView.showBindWithGuest(AccountActivity.this, userModel);
            }
        });

        Object firstGuestObj = QSDKHelper.getInstance().getItem(this, KEY, "");
        if (firstGuestObj != null) {
            String firstGuest = ((String)firstGuestObj;
            if (firstGuest != null && firstGuest.length() == 0) {
                QSDKHelper.getInstance().setItem(this, KEY, "1");
                isLoginInit = true;
                mAccountView.showLoginInit(this);
                return;
            }
        }

       init();
    }

    private void init() {
        if (!isHis) {
            UserModel uinfo = QSDKHelper.getInstance().getUserInfoModel(this);

            if (isBind) {
                mAccountView.showBind(this, uinfo);
                return;
            }

            if (isSwitch) {
                mAccountView.showLogin(this);
                return;
            }

            if (uinfo.isLogined()) {
                mAccountView.showLoading(this);
                return;
            }

            mAccountView.showLogin(this);
        }else{
            showLoading();
            QSDKHttp.getInstance().getHisList(this, new QResultCallback<QCommonResultListBean<HisModel>>() {
                @Override
                public void onSuccess(QCommonResultListBean<HisModel> response) {
                    hideLoading();
                    List<HisModel> list = new ArrayList<HisModel>();
                    if (!response.getBody().isEmpty()) {
                        for (HisModel m : response.getBody()) {
                            HisModel t = new HisModel(HisModel.ITEM_TYPE.ITEM_TYPE_SECTION, getAccountType(m.getAccount_type()), m.getAccount());
                            list.add(t);
                            for (HisModel.HisSubModel sub : m.getRoles()) {
                                list.add(new HisModel(HisModel.ITEM_TYPE.ITEM_TYPE_ITEM, sub.getServer_name(), sub.getRole_name(), sub.getRole_level()));
                            }
                        }
                    }
                    mAccountView.showHist(AccountActivity.this, list);
                }

                @Override
                public void onError(int code, String msg) {
                    hideLoading();
                    TipActivity.tip(AccountActivity.this, msg);
                    mAccountView.showHist(AccountActivity.this, new ArrayList<>());
                }
            });
        }
    }


    private HisModel.ACCOUNT_TYPE getAccountType(int accountType) {
        Map<Integer, HisModel.ACCOUNT_TYPE> map = new HashMap<Integer, HisModel.ACCOUNT_TYPE>(){
            {
                put(9, HisModel.ACCOUNT_TYPE.Guest);
                put(1, HisModel.ACCOUNT_TYPE.Account);
                put(2, HisModel.ACCOUNT_TYPE.Facebook);
                put(3, HisModel.ACCOUNT_TYPE.Apple);
                put(4, HisModel.ACCOUNT_TYPE.Google);
            }
        };
        if (map.containsKey(accountType)) {
            return map.get(accountType);
        }
        return HisModel.ACCOUNT_TYPE.Guest;
    }

    private void loginSuccess(UserModel.Type type, UserModel userModel) {
        userModel.setType(type.ordinal());
        QSDKHelper.getInstance().setUserModel(this, userModel);
        QSDK.getInstance().loginSuccess(userModel.getToken());
        LogManager.getInstance().login(this);
        LogManager.getInstance().retention(this, userModel.getDays(), null);
        if (userModel.isCreated()) LogManager.getInstance().register(this);
        finish();
    }

    private void loginGuest() {
        showLoading();
        QSDKHttp.getInstance().loginGuest(AccountActivity.this, new QResultCallback<QCommonResultBean<UserModel>>() {
            @Override
            public void onSuccess(QCommonResultBean<UserModel> response) {
                hideLoading();
                if (response.getBody().isCreated()) LogManager.getInstance().register(AccountActivity.this);
                if (isLoginInit) {
                    loginSuccess(UserModel.Type.Guest, response.getBody());
                }else{
                    mAccountView.showBindWithGuest(AccountActivity.this, response.getBody());
                }
            }

            @Override
            public void onError(int code, String msg) {
                hideLoading();
                TipActivity.tip(AccountActivity.this, msg);
            }
        });
    }

    private void loginToken() {
        showLoading();
        QSDKHttp.getInstance().loginToken(
                AccountActivity.this,
                QSDKHelper.getInstance().getUserInfoModel(this).getToken(),
                new QResultCallback<QCommonResultBean<UserModel>>() {
                    @Override
                    public void onSuccess(QCommonResultBean<UserModel> response) {
                        hideLoading();
                        UserModel userModel = QSDKHelper.getInstance().getUserInfoModel(AccountActivity.this);
                        response.getBody().setToken(userModel.getToken());
                        response.getBody().setPass(userModel.getPass());
                        response.getBody().setAccount(userModel.getAccount());
                        response.getBody().setType(userModel.getType());
                        loginSuccess(UserModel.Type.Token, response.getBody());
                    }

                    @Override
                    public void onError(int code, String msg) {
                        hideLoading();
                        TipActivity.tip(AccountActivity.this, msg);
                        QSDKHelper.getInstance().setUserModel(AccountActivity.this, new UserModel());
                        mAccountView.showLogin(AccountActivity.this);
                    }
                }
        );
    }

    private CallbackManager mCallbackManager;
    private void authFb(UserModel bindModel) {
        if (mCallbackManager == null) {
            mCallbackManager = CallbackManager.Factory.create();
            LoginManager.getInstance().registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
                @Override
                public void onSuccess(LoginResult loginResult) {
                    String token = loginResult.getAccessToken().getToken();
                    QSDKHttp.getInstance().bindFacebook(AccountActivity.this, token, bindModel != null ? bindModel.getToken() : "", new QResultCallback<QCommonResultBean<UserModel>>() {
                        @Override
                        public void onSuccess(QCommonResultBean<UserModel> response) {
                            hideLoading();
                            if (bindModel != null && response.getBody().getToken().length() == 0) response.getBody().setToken(bindModel.getToken());
                            loginSuccess(UserModel.Type.Facebook, response.getBody());
                        }

                        @Override
                        public void onError(int code, String msg) {
                            hideLoading();
                            TipActivity.tip(AccountActivity.this, msg);
                        }
                    });
                }

                @Override
                public void onCancel() {
                    hideLoading();
                }

                @Override
                public void onError(@NotNull FacebookException e) {
                    hideLoading();
                    TipActivity.tip(AccountActivity.this, e.getLocalizedMessage());
                }
            });
        }
        LoginManager.getInstance().logOut();
        LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile"));
        showLoading();
    }

    private void authApple(UserModel bindModel) {
        showLoading();
        AppleAuthActivity.startActivity(this, new QSDKListener(){

            @Override
            public void onAppleAuthSuccess(String code) {
                QSDKHttp.getInstance().bindApple(AccountActivity.this, code, bindModel != null ? bindModel.getToken() : "", new QResultCallback<QCommonResultBean<UserModel>>() {
                    @Override
                    public void onSuccess(QCommonResultBean<UserModel> response) {
                        hideLoading();
                        if (bindModel != null && response.getBody().getToken().length() == 0) response.getBody().setToken(bindModel.getToken());
                        loginSuccess(UserModel.Type.Apple, response.getBody());
                    }

                    @Override
                    public void onError(int code, String msg) {
                        hideLoading();
                        TipActivity.tip(AccountActivity.this, msg);
                    }
                });
            }

            @Override
            public void onAppleAuthClose() {
                hideLoading();
            }

            @Override
            public void onAppleAuthFail() {
                hideLoading();
                TipActivity.tip(AccountActivity.this, Language.System_Error.toString());
            }
        });
    }

    GoogleSignInClient mGoogleSignInClient;
    private int RC_SIGN_IN = 87212;
    private boolean isBindGoogle;
    private UserModel mBindModel;
    private void authGoogle(UserModel bindModel) {
        isBindGoogle = bindModel != null;
        mBindModel = bindModel;
        if (mGoogleSignInClient == null) {
            GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestEmail()
                    .requestId()
                    .requestProfile()
                    .requestIdToken(QSDKHelper.getInstance().getConfigureModel().getGoogleClientId())
                    .build();
            mGoogleSignInClient =  GoogleSignIn.getClient(this, gso);
        }
        mGoogleSignInClient.signOut().addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull @NotNull Task<Void> task) {
                showLoading();
                Intent signInIntent = mGoogleSignInClient.getSignInIntent();
                startActivityForResult(signInIntent, RC_SIGN_IN, new Bundle());
            }
        });
    }

    private UserModel getWaittingBindingUser() {
        return QSDKHelper.getInstance().getUserInfoModel(this);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (mCallbackManager != null) {
            mCallbackManager.onActivityResult(requestCode, resultCode, data);
        }
        if (requestCode == RC_SIGN_IN) {
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            try {
                // Google Sign In was successful, authenticate with Firebase
                GoogleSignInAccount account = task.getResult(ApiException.class);
                String email = account.getEmail();
                String token = account.getIdToken();

                QSDKHttp.getInstance().bindGoogle(this, token, email, isBindGoogle ? mBindModel.getToken() : "", new QResultCallback<QCommonResultBean<UserModel>>() {
                    @Override
                    public void onSuccess(QCommonResultBean<UserModel> response) {
                        hideLoading();
                        if (isBindGoogle && response.getBody().getToken().length() == 0) response.getBody().setToken(mBindModel.getToken());
                        loginSuccess(UserModel.Type.Google, response.getBody());
                    }

                    @Override
                    public void onError(int code, String msg) {
                        hideLoading();
                        TipActivity.tip(AccountActivity.this, msg);
                    }
                });


            } catch (ApiException e) {
                hideLoading();
                if (e.getStatusCode() == SIGN_IN_CANCELLED) {
                    return;
                }
                // Google Sign In failed, update UI appropriately
                //com.google.android.gms.common.api.ApiException: 10 firebase 的sha1指纹没添加
                //com.google.android.gms.common.api.ApiException: 7 网络问题
                Log.w(TAG, "signInResult:failed code=" + e.getStatusCode() + ",msg=>" + e.getLocalizedMessage());
                TipActivity.tip(this, e.getLocalizedMessage());
            }
        }
    }

    @Override
    public void onBackPressed() {
        if (mAccountView != null && isLoginInit && !mAccountView.isShowLoginInit(this)) {
            mAccountView.showLoginInit(this);
            return;
        }
        QSDK.getInstance().loginCancel();
        super.onBackPressed();
    }

    @Override
    protected void onDestroy() {
        hideLoading();
        mAccountView.hideAll(this);
        isHis = false;
        isBind = false;
        isSwitch = false;
        super.onDestroy();
    }
}
